import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Timestamp;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.PrinterState;
import javax.print.attribute.standard.PrinterStateReason;


public class TestPrint {

	

	public static void main(String[] args) throws IOException {

		//showPrinters();
		
		//fileShow();
		//printing();
		//checkSupportedFlavors();
		//boolean flag = printerReady();  System.out.println("flag = "+flag);
		//String content = "TEST";
		//updateLog(content);
		//String[] print = getPrinters(); for (int i = 0; i < print.length; i++) { System.out.println(i+"  "+print[i]);}		
		//showArgs(args);
		//*
		System.out.println(argDirExists(args[0]));
		System.out.println("===");
		System.out.println(argPrnExists(args));
		System.out.println("===");
		System.out.println(getArgPrn(args));
		//*/
		
		halt();
	}

	public static void showPrinters() {
		PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
		PrintService service = PrintServiceLookup.lookupDefaultPrintService();
		String str;
		if(services.length < 1)
		{
			System.out.println("Zero printers found!");
		}
		if(service != null)
		{
			str = service.getName();
			System.out.println("The deafult printer is:"+str);
			  System.out.println("===============");

		}
		for (int i = 0; i < services.length; i++) {
		   System.out.println(services[i].getName());
		}
	}
	
	public static String[] getPrinters()
	{
		PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);

		String[] printers = null;
		int length = services.length;
		
		if(services.length < 1)
		{
			System.out.println("Zero printers found!");
			return null;
		}
		else
		{
			printers = new String[length];
			
			for (int i = 0; i < length; i++) 
			{
				//System.out.println(services[i].getName());
				printers[i] = services[i].getName();
		   
			}
			return printers;
		}
		
	}
	
	public static void fileShow() 
	{
		 String path = System.getProperty("user.dir");
		 path = path +"\\Invoices\\";
		  
		  //Prints the working Directory
		  //System.out.println("Working Directory = "+path);
		   
		  
		  String str = path;
		 
		  System.out.println("=====Start of files=====");
		  
		  String files;
		  File folder = new File(path);
		  File[] listOfFiles = folder.listFiles(); 
		 
		  for (int i = 0; i < listOfFiles.length; i++) 
		  {
			  files = listOfFiles[i].getName();
			  System.out.println(files);
		  }
		  for (int i = 0; i < listOfFiles.length; i++) 
		  {
			  str = path;
			   if (listOfFiles[i].isFile()) 
			   {
			   files = listOfFiles[i].getName();
			       
			   		str = str +files;
			   		//*
			   		if (files.endsWith(".doc") || files.endsWith(".DOC")
			    		   ||files.endsWith(".docx")||files.endsWith(".DOCX"))
			        {
						System.out.println(str);
			        }
			        //*/
			   		/*
			   		System.out.println(files);
			   		//*/
			     }
			   str = null;
		   
		  }
		  System.out.println("=====End of files=====");
}

	public static void printing() throws IOException//CODE EXAMPLE. DOES NOT RUN!!!!!!!!!!
	{
		DocFlavor psFlavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
		//psFlavor = new DocFlavor("application/octet-stream", "java.io.InputStream");
        PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
        //aset.add(MediaSizeName.ISO_A4);
        //aset.add(new PrinterName("Microsoft XPS Document Writer", null));
        aset =null;
        System.out.println("Start");
        FileInputStream fis = null;
		try {
			fis = new FileInputStream("C:\\Users\\HellenicCableNetwork"
			        			+ "\\Workspace\\TestPrint\\Invoices\\test-doc.doc");
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
                	
        
        
        PrintService[] pservices = PrintServiceLookup.lookupPrintServices(psFlavor, aset);
        if (pservices.length > 0) {
                DocPrintJob pj = pservices[0].createPrintJob();
                try {
                        Doc doc = new SimpleDoc(fis, psFlavor, null);
                        pj.print(doc, aset);
                        System.out.println("All ok!");
                } catch (PrintException e) {
                        System.err.println(e);
                }
        }
        else
            System.out.println("no service");

	}

	public static void checkSupportedFlavors()
	{
		PrintService pss[] = PrintServiceLookup.lookupPrintServices(null, null);
		
		for (int i = 0; i < pss.length; ++i) 
		{
		      System.out.println(pss[i]);
		      PrintService ps = pss[i];

		      PrintServiceAttributeSet psas = ps.getAttributes();
		      Attribute attributes[] = psas.toArray();
		      
		      for (int j = 0; j < attributes.length; ++j) 
		      {
			        Attribute attribute = attributes[j];
			        System.out.println("  attribute: " + attribute.getName());
			        if (attribute instanceof PrinterName) 
			        {
			          System.out.println("    printer name: " + ((PrinterName) attribute).getValue());
			        }
		      }
		      
		      DocFlavor supportedFlavors[] = ps.getSupportedDocFlavors();
		      
		      for (int j = 0; j < supportedFlavors.length; ++j) 
		      {
		    	  	System.out.println("  flavor: " + supportedFlavors[j]);
		      }
		}
		
	}

	public static String printerStatus()
	{
		PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
		AttributeSet attributes = printService.getAttributes();
		
		String printerState = attributes.get(PrinterState.class).toString();
		String printerStateReason = attributes.get(PrinterStateReason.class).toString();

		
		// May be IDLE, PROCESSING, STOPPED or UNKNOWN
		System.out.println("printerState = " + printerState); 
		// If your printer state returns STOPPED, for example, you can identify the reason 
		System.out.println("printerStateReason = " + printerStateReason); 

		if (printerState.equals(PrinterState.STOPPED.toString())) {

		    if (printerStateReason.equals(PrinterStateReason.TONER_LOW.toString())) 
		    {
		        System.out.println("Toner level is low.");
		    }

			if(printerState.equals(PrinterState.IDLE.toString()))
			{
				return "IDLE";
			}
			
		}

		return printerState;
		
		

		
	}

	public static boolean printerReady()
	{
		
		boolean flag=false;
		
		PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
		AttributeSet attributes = printService.getAttributes();
		String printerState = null;
		
		if(attributes.get(PrinterState.class) != null)
		{
			printerState = attributes.get(PrinterState.class).toString();
			
			if(printerState.equals(PrinterState.IDLE.toString()))
			{
				flag = true;
			}
			else if(printerState.equals(PrinterState.PROCESSING.toString()))
			{
				flag = false;
			}
			else if(printerState.equals(PrinterState.STOPPED.toString()))
			{
				flag = false;
			}
			else if(printerState.equals(PrinterState.UNKNOWN.toString()))
			{
				flag = true;
			}
		}	
				
		return flag;
	}

	public static void printerFault()
	{
		PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
		AttributeSet attributes = printService.getAttributes();
		String printerState = null;
		String printerStateReason = null;
		if(attributes.get(PrinterState.class) != null)
		{
			printerState = attributes.get(PrinterState.class).toString();
			printerStateReason = attributes.get(PrinterStateReason.class).toString();
		
			
			if(printerState.equals(PrinterState.STOPPED.toString()))
			{
				// If the printer state returns STOPPED we identify the reason 		
				System.out.println("Printer stopped: " + printerStateReason); 
			}
		}
	}
	
	public static void updateLog(String content) //update the log with all operations

	{
		
		 java.util.Date date= new java.util.Date();
		 String timestamp = new Timestamp(date.getTime()).toString();
		 
		 
		try {
			String path = System.getProperty("user.dir");
			File file = new File(path+"\\log.txt");
 
			// if file doesnt exists, then create it
			if (!file.exists()) {
				file.createNewFile();
			}
			
			content = timestamp + " --- " + content;
			FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
			BufferedWriter bw = new BufferedWriter(fw);
			bw.newLine();
			bw.append(content);
			bw.close();
 
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
	
	//Checks if the given directory exists
	public static boolean argDirExists(String argStr)
	{
		
		File dir = new File(argStr);
		
		if (argStr != null && dir.isDirectory() == true)
		{
			//System.out.println("Dir: "+argStr);

			return true;
		}
		else 
		{
			System.out.println("Please enter a valid path.");
		}
		return false;
	}
	
	//Checks if a parameter printer is given and is correct
	public static boolean argPrnExists(String[] argStr)
	{
		int i,j;
		for(i=0;i<argStr.length;i++)
		{
			if(argStr[i].startsWith("-p"))
			{
				j=i+1;
				//System.out.println("Found -p: "+argStr[j]);
				if(argStr[j] == null)
				{
					System.out.println("Error - No argument given");
					return false;
				}
				if(checkPrnName(argStr[j])==true)
				{
					return true;
				}
				else 
				{
					System.out.println("Error - No such printer found");
					return false;
				}
			}
		}
		
		return false;
	}

	//Returns the printer name that corresponds from the one in the argument. 
	public static String getArgPrn(String[] argStr)
	{
		
		String prnName;
		int i,j;
		for(i=0;i<argStr.length;i++)
		{
			if(argStr[i].startsWith("-p"))
			{
				j = i+1;
				 prnName = getPrinterName(argStr[j]);
				 return prnName;
			}
		}		
		return null;
	}
	
	//Checks if the Night Operation option is enabled
	public static boolean argNExists(String[] argStr)
	{
		int i;
		for(i=0;i<argStr.length;i++)
		{
			if(argStr[i].startsWith("-n"))
			{
				return true;
			}
		}
		
		return false;
	}
		
	/*=======================================
	 * 			UTILITIES
	 ========================================*/

	//shows the arguments
	public static void showArgs(String[] argStr)
	{
		int i,length;
		length = argStr.length;
		
		for(i=0;i<length;i++)
		{
			System.out.println("Arg["+i+"]: "+argStr[i]);
		}
	}
	
	//Checks if the printer name given in the argument exists
	public static boolean checkPrnName(String prn)
	{
		String[] printers = getPrinters();
		for(int i=0;i<printers.length;i++)
		{
			if(printers[i].contains(prn))
			{
				return true;
			}
		}
		return false;
	}

	//Return the printer name that correspond more to the name given
	public static String getPrinterName(String prn)
	{
		String[] printers = getPrinters();
		for(int i=0;i<printers.length;i++)
		{
			if(printers[i].contains(prn))
			{
				return printers[i];
			}
		}
		return null;
	}
	
	public static void halt()
	{
		try {
	        System.in.read();
	    } catch (IOException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	    }
	}
	
}
